package com.zhou.essearch.controller;

import com.zhou.essearch.document.DocDocument;
import com.zhou.essearch.document.EsId;
import com.zhou.essearch.page.Page;
import com.zhou.essearch.page.PageRequest;
import com.zhou.essearch.service.EsSearchService;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * elasticsearch 搜索
 * @author jiangshicun
 * @version 0.1
 * @date 2020/01/13 15:09
 */
@Api(tags={"Es"})
@RestController
@RequestMapping("es")
public class EsSearchController {
    private Logger log = LoggerFactory.getLogger(getClass());

    @Resource
    private EsSearchService esSearchService;

    /**
     * 新增 / 修改索引
     * @return
     */
    @RequestMapping("api")
    public String add(@RequestBody DocDocument DocDocument) {
        esSearchService.save(DocDocument);
        return "success";
    }

    /**
     * 删除索引
     * @return
     */
    @RequestMapping("delete/{id}")
    public String delete(@PathVariable String id) {
        esSearchService.delete(id);
        return "success";
    }

    @RequestMapping("deleteById")
    public String deleteById(String id) {
        esSearchService.delete(id);
        return "success";
    }
    /**
     * 清空索引
     * @return
     */
    @RequestMapping("delete_all")
    public String deleteAll(@PathVariable String id) {
        esSearchService.deleteAll();
        return "success";
    }

    /**
     * 根据ID获取
     * @return
     */
    @RequestMapping("get/{id}")
    public DocDocument getById(@PathVariable String id){

        return esSearchService.getById(id);
    }

    @RequestMapping(value="getByIdNew", method=RequestMethod.GET)
    public DocDocument getByIdNew(@RequestParam(name = "id") String id){
        return esSearchService.getById(id);
    }
    /**
     * 根据获取全部
     * @return
     */
    @RequestMapping("get_all")
    public List<DocDocument> getAll(){
        return esSearchService.getAll();
    }

    /**
     * 搜索
     * @param keyword
     * @return
     */
    @RequestMapping("query/{keyword}")
    public List<DocDocument> query(@PathVariable String keyword){
        return esSearchService.query(keyword,DocDocument.class);
    }

    /**
     * 搜索，命中关键字高亮
     * http://localhost:8080/query_hit?keyword=无印良品荣耀&indexName=orders&fields=productName,productDesc
     * @param keyword   关键字
     * @param indexName 索引库名称
     * @param fields    搜索字段名称，多个以“，”分割
     * @return
     */
    @RequestMapping("query_hit")
    public List<Map<String,Object>> queryHit(@RequestParam String keyword, @RequestParam String indexName, @RequestParam String fields){
        String[] fieldNames = {};
        if(fields.contains(",")) {
            fieldNames = fields.split(",");
        } else {
            fieldNames[0] = fields;
        }
        return esSearchService.queryHit(keyword,indexName,fieldNames);
    }
    @RequestMapping("query_hit_new")
    public List<Map<String,Object>> queryHit(@RequestBody PageRequest pageRequest){
        String[] fieldNames = {};
        String fields = pageRequest.getFields();
        String indexName = pageRequest.getIndexName();
        String keyword = pageRequest.getKeyword();
        List<Map<String,Object>> list=new ArrayList<>();
        if("".equals(keyword)){
            List<DocDocument> all = esSearchService.getAll();
            int size=all.size();
            if(all==null||size==0){
                return new ArrayList<>();
            }else{

                for (int i = 0; i <size ; i++) {
                    DocDocument docDocument = all.get(i);
                    Map<String, Object> map = parseObj2Map(docDocument);
                        list.add(map);
                }
                return list;
            }
        }
        if(fields.contains(",")) {
            fieldNames = fields.split(",");
        } else {
            fieldNames[0] = fields;
        }
        List<Map<String, Object>> esList = esSearchService.queryHit(keyword, indexName, fieldNames);
        if(esList==null||esList.size()==0){
            return esList;
        }
        for (int i = 0; i < esList.size(); i++) {
            HashMap<String,Object> map = (HashMap<String, Object>) esList.get(i).get("source");
            list.add(map);
        }

        return list;
    }

    public static Map<String, Object> parseObj2Map(Object args) {
        return Arrays.stream(BeanUtils.getPropertyDescriptors(args.getClass()))
                .filter(pd -> !"class".equals(pd.getName()))
                .collect(HashMap::new,
                        (map, pd) -> map.put(pd.getName(), ReflectionUtils.invokeMethod(pd.getReadMethod(), args)),
                        HashMap::putAll);
    }


    /**
     * 搜索，命中关键字高亮
     * http://localhost:8080/query_hit_page?keyword=无印良品荣耀&indexName=orders&fields=productName,productDesc&pageNo=1&pageSize=1
     * @param pageNo    当前页
     * @param pageSize  每页显示的数据条数
     * @param keyword   关键字
     * @param indexName 索引库名称
     * @param fields    搜索字段名称，多个以“，”分割
     * @return
     */
    @RequestMapping("query_hit_page")
    public Page<Map<String,Object>> queryHitByPage(@RequestParam int pageNo,@RequestParam int pageSize
                                                    ,@RequestParam String keyword, @RequestParam String indexName, @RequestParam String fields){
        String[] fieldNames = {};
        if(fields.contains(",")) {
            fieldNames = fields.split(",");
        } else {
            fieldNames[0] = fields;
        }
        return esSearchService.queryHitByPage(pageNo,pageSize,keyword,indexName,fieldNames);
    }

    /**
     * 删除索引库
     * @param indexName
     * @return
     */
    @RequestMapping("delete_index/{indexName}")
    public String deleteIndex(@PathVariable String indexName){
        esSearchService.deleteIndex(indexName);
        return "success";
    }
}
